package A1_3_School;
import java.util.Arrays;

public class SchoolTest {
    public static void main(String[] args) {
        System.out.println("=== 学校管理系统测试 ===\n");

        // 1. 创建学院
        School computerSchool = new School("SCH001", "计算机学院");
        System.out.println("创建学院: " + computerSchool.getSchoolName());

        // 2. 创建系
        Department csDepartment = new Department("D001", "计算机科学系");
        Department seDepartment = new Department("D002", "软件工程系");

        computerSchool.addDepartment(csDepartment);
        computerSchool.addDepartment(seDepartment);
        System.out.println("添加系: " + csDepartment.getDepartmentName() + ", " + seDepartment.getDepartmentName());

        // 3. 创建课程
        Subject java = new Subject("S001", "Java编程", 4);
        Subject database = new Subject("S002", "数据库系统", 3);
        Subject algorithms = new Subject("S003", "算法设计", 4);
        Subject webDev = new Subject("S004", "Web开发", 3);
        Subject softwareEngineering = new Subject("S005", "软件工程", 3);
        Subject dataStructures = new Subject("S006", "数据结构", 4);

        // 4. 将课程添加到系
        csDepartment.addSubject(java);
        csDepartment.addSubject(algorithms);
        csDepartment.addSubject(dataStructures);

        seDepartment.addSubject(database);
        seDepartment.addSubject(webDev);
        seDepartment.addSubject(softwareEngineering);

        System.out.println("\n课程分配完成:");
        System.out.println(csDepartment.getDepartmentName() + " 课程: " +
                Arrays.toString(csDepartment.getSubjects().stream()
                        .map(Subject::getSubjectName).toArray()));
        System.out.println(seDepartment.getDepartmentName() + " 课程: " +
                Arrays.toString(seDepartment.getSubjects().stream()
                        .map(Subject::getSubjectName).toArray()));

        // 5. 创建教师
        Instructor profZhang = new Instructor("I001", "张教授");
        Instructor profLi = new Instructor("I002", "李教授");
        Instructor profWang = new Instructor("I003", "王教授");
        Instructor profZhao = new Instructor("I004", "赵教授");

        // 6. 为教师分配课程
        profZhang.assignSubject(java);
        profZhang.assignSubject(algorithms);

        profLi.assignSubject(database);
        profLi.assignSubject(webDev);

        profWang.assignSubject(dataStructures);
        profWang.assignSubject(softwareEngineering);

        profZhao.assignSubject(java); // 同一门课程可以有多个教师
        profZhao.assignSubject(webDev);

        // 测试教师课程数量限制
        System.out.println("\n测试教师课程数量限制:");
        Subject testSubject1 = new Subject("S007", "测试课程1", 1);
        Subject testSubject2 = new Subject("S008", "测试课程2", 1);
        Subject testSubject3 = new Subject("S009", "测试课程3", 1);
        Subject testSubject4 = new Subject("S010", "测试课程4", 1);

        profZhang.assignSubject(testSubject1);
        profZhang.assignSubject(testSubject2);
        profZhang.assignSubject(testSubject3); // 应该成功
        profZhang.assignSubject(testSubject4); // 应该失败，超过3门限制

        // 7. 将教师添加到系
        csDepartment.addInstructor(profZhang);
        csDepartment.addInstructor(profWang);

        seDepartment.addInstructor(profLi);
        seDepartment.addInstructor(profZhao);

        System.out.println("\n教师分配完成:");
        System.out.println(csDepartment.getDepartmentName() + " 教师: " +
                Arrays.toString(csDepartment.getInstructors().stream()
                        .map(Instructor::getName).toArray()));
        System.out.println(seDepartment.getDepartmentName() + " 教师: " +
                Arrays.toString(seDepartment.getInstructors().stream()
                        .map(Instructor::getName).toArray()));

        // 8. 创建学生
        Student student1 = new Student("ST001", "张三");
        Student student2 = new Student("ST002", "李四");
        Student student3 = new Student("ST003", "王五");
        Student student4 = new Student("ST004", "赵六");

        // 9. 学生选课
        student1.enrollSubject(java);
        student1.enrollSubject(algorithms);
        student1.enrollSubject(dataStructures);

        student2.enrollSubject(database);
        student2.enrollSubject(webDev);
        student2.enrollSubject(softwareEngineering);
        student2.enrollSubject(java);

        student3.enrollSubject(java);
        student3.enrollSubject(database);
        student3.enrollSubject(algorithms);
        student3.enrollSubject(webDev);
        student3.enrollSubject(softwareEngineering); // 5门课程

        student4.enrollSubject(dataStructures);
        student4.enrollSubject(java);

        // 测试学生选课数量限制
        System.out.println("\n测试学生选课数量限制:");
        Subject extraSubject = new Subject("S011", "额外课程", 1);
        student3.enrollSubject(extraSubject); // 应该失败，超过5门限制

        // 10. 将学生添加到学院
        computerSchool.enrollStudent(student1);
        computerSchool.enrollStudent(student2);
        computerSchool.enrollStudent(student3);
        computerSchool.enrollStudent(student4);

        // 11. 显示学院完整信息
        computerSchool.displaySchoolInfo();

        // 12. 显示详细信息
        displayDetailedInfo(computerSchool);

        // 13. 测试各种查询功能
        testQueryFunctions(computerSchool);
    }

    private static void displayDetailedInfo(School school) {
        System.out.println("\n=== 详细信息 ===");

        // 显示各系详情
        for (Department dept : school.getDepartments()) {
            System.out.println("\n" + dept.getDepartmentName() + " 详细信息:");

            System.out.println("教师列表:");
            for (Instructor instructor : dept.getInstructors()) {
                System.out.println("  - " + instructor.getName() +
                        " (ID: " + instructor.getInstructorId() + ")" +
                        " - 教授 " + instructor.getTeachingSubjects().size() + " 门课程:");
                for (Subject subject : instructor.getTeachingSubjects()) {
                    System.out.println("    * " + subject.getSubjectName() +
                            " (" + subject.getCredits() + "学分)");
                }
            }

            System.out.println("课程列表:");
            for (Subject subject : dept.getSubjects()) {
                System.out.println("  - " + subject.getSubjectName() +
                        " (ID: " + subject.getSubjectId() +
                        ", " + subject.getCredits() + "学分)");
            }
        }

        // 显示学生选课情况
        System.out.println("\n学生选课情况:");
        for (Student student : school.getStudents()) {
            System.out.println("  - " + student.getName() +
                    " (ID: " + student.getStudentId() + ")" +
                    " 选了 " + student.getSubjects().size() + " 门课程:");
            for (Subject subject : student.getSubjects()) {
                System.out.println("    * " + subject.getSubjectName() +
                        " (" + subject.getCredits() + "学分)");
            }
            // 计算总学分
            int totalCredits = student.getSubjects().stream()
                    .mapToInt(Subject::getCredits)
                    .sum();
            System.out.println("    总学分: " + totalCredits);
        }
    }

    private static void testQueryFunctions(School school) {
        System.out.println("\n=== 功能测试 ===");

        // 测试1: 查找教授特定课程的教师
        String targetCourse = "Java编程";
        System.out.println("\n教授 '" + targetCourse + "' 的教师:");
        for (Department dept : school.getDepartments()) {
            for (Instructor instructor : dept.getInstructors()) {
                for (Subject subject : instructor.getTeachingSubjects()) {
                    if (subject.getSubjectName().equals(targetCourse)) {
                        System.out.println("  - " + instructor.getName() +
                                " (" + dept.getDepartmentName() + ")");
                    }
                }
            }
        }

        // 测试2: 统计各系学生数量（通过课程关联）
        System.out.println("\n各系课程选课情况:");
        for (Department dept : school.getDepartments()) {
            int studentCount = 0;
            for (Subject subject : dept.getSubjects()) {
                for (Student student : school.getStudents()) {
                    if (student.getSubjects().contains(subject)) {
                        studentCount++;
                    }
                }
            }
            System.out.println("  - " + dept.getDepartmentName() +
                    ": " + studentCount + " 人次选课");
        }

        // 测试3: 显示热门课程（选课人数最多的课程）
        System.out.println("\n课程选课人数统计:");
        for (Department dept : school.getDepartments()) {
            for (Subject subject : dept.getSubjects()) {
                int enrollmentCount = 0;
                for (Student student : school.getStudents()) {
                    if (student.getSubjects().contains(subject)) {
                        enrollmentCount++;
                    }
                }
                System.out.println("  - " + subject.getSubjectName() +
                        ": " + enrollmentCount + " 人选修");
            }
        }

        // 测试4: 验证关系完整性
        System.out.println("\n系统完整性验证:");
        boolean systemValid = true;

        // 检查每个系是否有至少1位教师和1门课程
        for (Department dept : school.getDepartments()) {
            if (dept.getInstructors().isEmpty()) {
                System.out.println("  ❌ " + dept.getDepartmentName() + " 没有教师");
                systemValid = false;
            }
            if (dept.getSubjects().isEmpty()) {
                System.out.println("  ❌ " + dept.getDepartmentName() + " 没有课程");
                systemValid = false;
            }
        }

        // 检查每位教师是否至少教授1门课程
        for (Department dept : school.getDepartments()) {
            for (Instructor instructor : dept.getInstructors()) {
                if (instructor.getTeachingSubjects().isEmpty()) {
                    System.out.println("  ❌ " + instructor.getName() + " 没有教授任何课程");
                    systemValid = false;
                }
            }
        }

        if (systemValid) {
            System.out.println("  ✅ 所有关系完整性检查通过");
        }

        System.out.println("\n=== 测试完成 ===");
    }
}
